import logging
import os


class Logger(object):
    # 日志级别关系映射
    level_relations = {
        'debug': logging.DEBUG,
        'info': logging.INFO,
        'warning': logging.WARNING,
        'error': logging.ERROR,
        'crit': logging.CRITICAL
    }  # 日志的主要分类，每类对应一个级别，'DEBUG'级别最小, 'CRITICAL'级别最高

    def __init__(self, root_path, log_name, level='info',
                 fmt="时间:%(asctime)s, 第%(lineno)d行, 等级:%(levelname)s, 信息:%(message)s, 路径:%(pathname)s"):
        """
        初始化Logger类

        参数:
        root_path - 日志文件的根路径
        log_name - 日志文件的名称
        level - 日志级别，默认为'info'
        fmt - 日志的输出格式
        """
        # 指定日志保存的路径
        self.root_path = root_path

        # 初始logger名称和格式
        self.log_name = log_name

        # 初始格式
        self.fmt = fmt

        # 创建一个日志器对象
        self.logger = logging.getLogger(log_name)
        # 设置日志器的日志级别(类字典变量level_relations进行映射)
        self.logger.setLevel(self.level_relations[level])

    def get_logger(self):
        """
        获取日志器实例

        返回:
        logger - 配置好的日志器实例
        """
        # 拼接日志文件的路径
        path = os.path.join(self.root_path, 'log')
        # 确保日志文件路径存在，不存在则创建
        os.makedirs(path, exist_ok=True)  # exist_ok=True(默认False) 如果文件夹已经存在不报错
        # 日志的文件路径和名称
        file_name = os.path.join(path, self.log_name + '.log')
        # 创建一个文件处理器，用于写入日志文件
        rotate_handler = logging.FileHandler(file_name, encoding='utf-8', mode='a')  # 文件处理器 文件路径名 编码 追加模式

        # 创建一个格式器，用于格式化日志信息
        the_formatter = logging.Formatter(self.fmt)
        # 设置文件处理器的日志格式
        rotate_handler.setFormatter(the_formatter)

        # 将文件处理器添加到日志器中
        self.logger.addHandler(rotate_handler)

        # 返回配置好的日志器实例
        return self.logger


if __name__ == '__main__':
    logger = Logger(root_path='../', log_name='test_log', level='debug')
    logger = logger.get_logger()

    logger.debug("程序正则debug...")
    logger.info("程序info信息...")
    logger.warning("程序发生了warning...")
    logger.error("程序发生了error...")
    logger.critical("程序发生了危险...")
